package org.example.controller.platform;

import cn.dev33.satoken.annotation.SaCheckLogin;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.example.common.result.Result;
import org.example.controller.dto.CreatePlatformRoleRequest;
import org.example.controller.dto.UpdatePlatformRoleRequest;
import org.example.entity.Permission;
import org.example.entity.Role;
import org.example.service.PermissionService;
import org.example.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 平台端角色管理控制器
 * 管理平台端角色，不涉及租户概念
 */
@RestController
@RequestMapping("/platform/roles")
@Slf4j
@Tag(name = "平台端-角色管理", description = "平台端角色管理相关接口")
// @SecurityRequirement(name = "platformBearerAuth")  // 临时注释掉测试
public class RoleController {

    @Autowired
    private RoleService roleService;
    
    @Autowired
    private PermissionService permissionService;
    
    @Autowired
    private org.example.mapper.UserRolePlatformRelationMapper userRolePlatformRelationMapper;

    /**
     * 判断平台端角色是否受保护（不能删除/编辑）
     */
    private boolean isProtectedPlatformRole(Role role) {
        String roleName = role.getRoleName();
        
        // 超级管理员不能删除/编辑
        if ("超级管理员".equals(roleName)) {
            return true;
        }
        
        // 默认角色不能删除/编辑
        if ("默认角色".equals(roleName)) {
            return true;
        }
        
        // 主办会计不能删除/编辑
        if ("主办会计".equals(roleName)) {
            return true;
        }
        
        // 默认角色不能删除（可以根据roleCode或其他标识判断）
        if (role.getRoleCode() != null && role.getRoleCode().contains("DEFAULT")) {
            return true;
        }
        
        return false;
    }

    /**
     * 生成角色编码
     * 基于角色名称生成唯一的roleCode
     */
    private String generateRoleCode(String roleName) {
        if (roleName == null || roleName.trim().isEmpty()) {
            return "ROLE_" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
        }
        
        // 方案1：基于角色名称生成（推荐）
        String code = roleName.trim()
                .replaceAll("[\\s\\-_]+", "_")  // 空格、横线、下划线统一为下划线
                .replaceAll("[^a-zA-Z0-9_]", "") // 只保留字母、数字、下划线
                .toUpperCase();
        
        // 如果为空或太短，添加前缀
        if (code.isEmpty() || code.length() < 3) {
            code = "ROLE_" + code;
        }
        
        // 添加时间戳确保唯一性
        String timestamp = String.valueOf(System.currentTimeMillis()).substring(8);
        return code + "_" + timestamp;
    }



    /**
     * 平台角色摘要列表（用于左侧菜单）
     */
    @SaCheckLogin
    @GetMapping
    public Result<List<Map<String,Object>>> getPlatformRoleSummary() {
        try {
            // 基础角色列表
            List<Role> roles = roleService.getPlatformRoleList(1, Integer.MAX_VALUE, null).getRecords();
            
            // 统计数量（从 user_role_platform_relations 聚合）
            var counts = new HashMap<Long, Long>();
            List<Map<String,Object>> countList = roleService.countUsersByRoleId();
            if (countList != null) {
                for (Map<String,Object> row : countList) {
                    Object roleIdObj = row.get("roleId");
                    Object cntObj = row.get("userCount");
                    if (roleIdObj instanceof Number && cntObj instanceof Number) {
                        counts.put(((Number) roleIdObj).longValue(), ((Number) cntObj).longValue());
                    }
                }
            }

            List<Map<String,Object>> data = roles.stream().map(r -> {
                Map<String,Object> m = new HashMap<>();
                m.put("id", r.getId());
                m.put("roleName", r.getRoleName());
                m.put("userCount", counts.getOrDefault(r.getId(), 0L));
                return m;
            }).toList();
            return Result.success(data);
        } catch (Exception e) {
            log.error("查询平台角色摘要失败", e);
            return Result.error("查询平台角色列表失败");
        }
    }

    /**
     * 根据ID查询平台角色详情
     */
    @SaCheckLogin
    @GetMapping("/{roleId}")
    public Result<Map<String, Object>> getPlatformRoleById(@PathVariable Long roleId) {
        try {
            // TODO: 权限检查
            Role role = roleService.getPlatformRoleById(roleId);
            if (role == null) {
                return Result.notFound("角色不存在");
            }

            // 获取角色拥有的权限详情列表
            List<Permission> permissions = roleService.getPermissionsByRoleId(roleId);
            
            // 构建权限信息列表（包含编码和中文名称）
            List<Map<String, Object>> permissionList = permissions.stream().map(permission -> {
                Map<String, Object> permInfo = new HashMap<>();
                permInfo.put("code", permission.getPermissionCode());
                permInfo.put("name", permission.getPermissionName());
                return permInfo;
            }).collect(Collectors.toList());
            
            // 构建权限编码列表（保持向后兼容）
            List<String> permissionCodes = permissions.stream()
                    .map(Permission::getPermissionCode)
                    .collect(Collectors.toList());

            // 构建返回对象
            Map<String, Object> response = new HashMap<>();
            response.put("id", role.getId());
            response.put("roleName", role.getRoleName());
            response.put("roleCode", role.getRoleCode());
            response.put("description", role.getDescription());
            response.put("isActive", role.getIsActive());
            response.put("createdAt", role.getCreatedAt());
            response.put("permissionCodes", permissionCodes);
            response.put("permissions", permissionList);

            return Result.success(response);
        } catch (Exception e) {
            log.error("查询平台角色详情失败: {}", roleId, e);
            return Result.error("查询平台角色详情失败");
        }
    }

    /**
     * 创建新平台角色
     */
    @SaCheckLogin
    @PostMapping
    @Transactional
    public Result<Map<String, Object>> createPlatformRole(@RequestBody CreatePlatformRoleRequest req) {
        try {
            log.info("开始创建角色: {}", req.getRoleName());
            
            // TODO: 权限检查
            // 1) 先创建角色基本信息
            Role role = new Role();
            role.setRoleName(req.getRoleName());
            // 自动生成roleCode：基于角色名称生成
            String roleCode = generateRoleCode(req.getRoleName());
            role.setRoleCode(roleCode);
            log.info("准备创建角色，roleCode: {}", roleCode);
            
            Role created = roleService.createPlatformRole(role);
            log.info("角色创建成功，ID: {}", created.getId());

            // 2) 获取所有平台权限的code到真实ID映射
            log.info("开始获取平台权限映射");
            List<Permission> allPerms = roleService.getPlatformPermissions();
            log.info("获取到 {} 个平台权限", allPerms.size());
            
            Map<String, Long> codeToRealId = new HashMap<>();
            for (Permission p : allPerms) {
                if (p != null && p.getPermissionCode() != null && p.getId() != null) {
                    codeToRealId.put(p.getPermissionCode(), p.getId());
                }
            }
            log.info("权限码映射: {}", codeToRealId);

            List<Long> realPermissionIds = new ArrayList<>();
            
            // 优先使用 permissionCodes（推荐方式）
            if (req.getPermissionCodes() != null && !req.getPermissionCodes().isEmpty()) {
                log.info("使用permissionCodes方式分配权限: {}", req.getPermissionCodes());
                for (String code : req.getPermissionCodes()) {
                    Long realId = codeToRealId.get(code);
                    if (realId == null) {
                        log.error("无效的权限code: {}", code);
                        throw new IllegalArgumentException("无效的权限code: " + code);
                    }
                    realPermissionIds.add(realId);
                    log.info("权限码 {} 映射到ID: {}", code, realId);
                }
            }
            // 兼容旧的 permissionIds 方式
            else if (req.getPermissionIds() != null && !req.getPermissionIds().isEmpty()) {
                log.info("使用permissionIds方式分配权限: {}", req.getPermissionIds());
                // 复用分配接口里的映射逻辑
                Map<Integer, String> displayIdToCode = new HashMap<>();
                displayIdToCode.put(101, "platform:list:view");
                displayIdToCode.put(102, "platform:list:approve");
                displayIdToCode.put(103, "platform:settlement:view");
                displayIdToCode.put(104, "platform:settlement:export");
                displayIdToCode.put(105, "platform:enterprise:view");
                displayIdToCode.put(106, "platform:feedback:reply");
                displayIdToCode.put(107, "platform:report:manage");

                for (Long pid : req.getPermissionIds()) {
                    if (pid == null) continue;
                    int asInt = pid.intValue();
                    String code = displayIdToCode.get(asInt);
                    if (code != null) {
                        Long realId = codeToRealId.get(code);
                        if (realId == null) {
                            log.error("无效的权限编号: {} (找不到对应权限code)", asInt);
                            throw new IllegalArgumentException("无效的权限编号:" + asInt + " (找不到对应权限code)");
                        }
                        realPermissionIds.add(realId);
                    } else {
                        realPermissionIds.add(pid);
                    }
                }
            }

            // 分配权限
            if (!realPermissionIds.isEmpty()) {
                log.info("开始分配权限，权限ID列表: {}", realPermissionIds);
                roleService.assignPlatformRolePermissions(created.getId(), realPermissionIds);
                log.info("权限分配完成");
            } else {
                log.info("没有权限需要分配");
            }

            Map<String, Object> resp = new HashMap<>();
            resp.put("id", created.getId());
            log.info("角色创建流程完成，返回ID: {}", created.getId());
            return Result.success("平台角色创建成功", resp);
        } catch (Exception e) {
            log.error("创建平台角色失败", e);
            return Result.error("创建平台角色失败: " + e.getMessage());
        }
    }

    /**
     * 更新平台角色信息
     */
    @SaCheckLogin
    @PutMapping("/{roleId}")
    @Transactional
    public Result<Role> updatePlatformRole(@PathVariable Long roleId, @RequestBody UpdatePlatformRoleRequest req) {
        try {
            // TODO: 权限检查
            Role existingRole = roleService.getPlatformRoleById(roleId);
            if (existingRole == null) {
                return Result.error("角色不存在");
            }
            
            // 业务规则检查：受保护的角色不能编辑
            if (isProtectedPlatformRole(existingRole)) {
                return Result.error("该角色受保护，不能编辑");
            }
            
            Role roleToUpdate = new Role();
            roleToUpdate.setId(roleId);
            roleToUpdate.setRoleName(req.getRoleName());

            // 更新权限
            if (req.getPermissionCodes() != null && !req.getPermissionCodes().isEmpty()) {
                List<Permission> allPerms = roleService.getPlatformPermissions();
                Map<String, Long> codeToRealId = new HashMap<>();
                for (Permission p : allPerms) {
                    if (p != null && p.getPermissionCode() != null && p.getId() != null) {
                        codeToRealId.put(p.getPermissionCode(), p.getId());
                    }
                }
                List<Long> realPermissionIds = new ArrayList<>();
                for (String code : req.getPermissionCodes()) {
                    Long realId = codeToRealId.get(code);
                    if (realId == null) {
                        throw new IllegalArgumentException("无效的权限code: " + code);
                    }
                    realPermissionIds.add(realId);
                }
                roleService.assignPlatformRolePermissions(roleId, realPermissionIds);
            }

            Role updatedRole = roleService.updatePlatformRole(roleToUpdate);
            return Result.success("平台角色更新成功", updatedRole);
        } catch (Exception e) {
            log.error("更新平台角色失败: {}", roleId, e);
            return Result.error("更新平台角色失败: " + e.getMessage());
        }
    }

    /**
     * 删除平台角色
     */
    @SaCheckLogin
    @DeleteMapping("/{roleId}")
    public Result<String> deletePlatformRole(@PathVariable Long roleId) {
        try {
            // TODO: 权限检查
            Role role = roleService.getPlatformRoleById(roleId);
            if (role == null) {
                return Result.error("角色不存在");
            }
            
            // 业务规则检查：受保护的角色不能删除
            if (isProtectedPlatformRole(role)) {
                return Result.error("该角色受保护，不能删除");
            }
            
            // 检查是否有用户使用该角色
            List<Map<String,Object>> countList = roleService.countUsersByRoleId();
            Map<Long, Long> counts = countList.stream()
                .collect(Collectors.toMap(
                    m -> (Long) m.get("roleId"), 
                    m -> (Long) m.get("userCount")
                ));
            
            Long userCount = counts.getOrDefault(roleId, 0L);
            
            // 如果有用户使用该角色，转移到默认角色
            if (userCount > 0) {
                Role defaultRole = roleService.getDefaultPlatformRole();
                if (defaultRole == null) {
                    return Result.error("找不到默认角色，无法转移用户");
                }
                
                // 转移用户到默认角色
                int transferredCount = userRolePlatformRelationMapper.transferUsersToNewRole(roleId, defaultRole.getId());
                log.info("已将 {} 个用户从角色 {} 转移到默认角色 {}", transferredCount, role.getRoleName(), defaultRole.getRoleName());
            }
            
            roleService.deletePlatformRole(roleId);
            return Result.success("平台角色删除成功");
        } catch (Exception e) {
            log.error("删除平台角色失败: {}", roleId, e);
            return Result.error("删除平台角色失败: " + e.getMessage());
        }
    }

    /**
     * 为平台角色分配权限
     */
    @SaCheckLogin
    @PostMapping("/{roleId}/permissions")
    public Result<String> assignPlatformRolePermissions(@PathVariable Long roleId, @RequestBody List<Long> permissionIds) {
        try {
            // TODO: 权限检查
            // 兼容 displayId(101~107) 与 数据库真实ID 的混合入参
            // 1) 构建 displayId -> code 映射
            Map<Integer, String> displayIdToCode = new HashMap<>();
            displayIdToCode.put(101, "platform:list:view");
            displayIdToCode.put(102, "platform:list:approve");
            displayIdToCode.put(103, "platform:settlement:view");
            displayIdToCode.put(104, "platform:settlement:export");
            displayIdToCode.put(105, "platform:enterprise:view");
            displayIdToCode.put(106, "platform:feedback:reply");
            displayIdToCode.put(107, "platform:report:manage");

            // 2) code -> 实际DB id 映射
            List<Permission> allPerms = roleService.getPlatformPermissions();
            Map<String, Long> codeToRealId = new HashMap<>();
            for (Permission p : allPerms) {
                if (p != null && p.getPermissionCode() != null && p.getId() != null) {
                    codeToRealId.put(p.getPermissionCode(), p.getId());
                }
            }

            // 3) 归一化成真实ID
            List<Long> realPermissionIds = new java.util.ArrayList<>();
            for (Long pid : permissionIds) {
                if (pid == null) continue;
                int asInt = pid.intValue();
                String code = displayIdToCode.get(asInt);
                if (code != null) {
                    Long realId = codeToRealId.get(code);
                    if (realId == null) {
                        throw new IllegalArgumentException("无效的权限编号:" + asInt + " (找不到对应权限code)");
                    }
                    realPermissionIds.add(realId);
                } else {
                    // 当作真实ID直传
                    realPermissionIds.add(pid);
                }
            }

            roleService.assignPlatformRolePermissions(roleId, realPermissionIds);
            return Result.success("平台角色权限分配成功");
        } catch (Exception e) {
            log.error("分配平台角色权限失败: {} -> {}", roleId, permissionIds, e);
            return Result.error("分配权限失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有平台权限列表（用于权限分配）
     */
    @SaCheckLogin
    @GetMapping("/permissions")
    public Result<List<Permission>> getPlatformPermissions() {
        try {
            // TODO: 权限检查
            List<Permission> permissions = roleService.getPlatformPermissions();
            return Result.success(permissions);
        } catch (Exception e) {
            log.error("获取平台权限列表失败", e);
            return Result.error("获取平台权限列表失败");
        }
    }

    /**
     * 启用/禁用平台角色
     */
    @SaCheckLogin
    @PatchMapping("/{roleId}/status")
    public Result<String> updatePlatformRoleStatus(@PathVariable Long roleId, @RequestParam Integer isActive) {
        try {
            // TODO: 权限检查
            roleService.updatePlatformRoleStatus(roleId, isActive);
            return Result.success("平台角色状态更新成功");
        } catch (Exception e) {
            log.error("更新平台角色状态失败: {} -> {}", roleId, isActive, e);
            return Result.error("更新平台角色状态失败: " + e.getMessage());
        }
    }
}
